﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;

/**
 * C#的反射
 * 依赖注入： DependencyInjection 
 * |- Microsoft.Extensions.DependencyInjection
 * 
 */
namespace BiliBiliCSharpStudy.clazz.ch29.d05 {
    class IspExample05 {
        public static void Demo() {
            Test4();
        }

        public static void Test4() {
            var sc = new ServiceCollection();
            sc.AddScoped(typeof(ITank), typeof(HeavyTank));
            sc.AddScoped(typeof(IVehicle), typeof(Car));
            sc.AddScoped<Driver>();
            var sp = sc.BuildServiceProvider();
            // =========== 华丽的分割线 ===========
            ITank tank = sp.GetService<ITank>();
            tank.Fire();
            tank.Run();
            var driver = sp.GetService<Driver>();
            driver.Drive();
        }

        public static void Test3() {
            var sc = new ServiceCollection();
            sc.AddScoped(typeof(ITank), typeof(HeavyTank));
            var sp = sc.BuildServiceProvider();
            // =========== 华丽的分割线 ===========
            ITank tank = sp.GetService<ITank>();
            tank.Fire();
            tank.Run();
        }

        public static void Test2() {
            ITank tank = new HeavyTank();
            // =========== 华丽的分割线 ===========
            var t = tank.GetType();
            object obj = Activator.CreateInstance(t);
            MethodInfo fireMi = t.GetMethod("Fire");
            MethodInfo runMi = t.GetMethod("Run");
            fireMi.Invoke(obj, null);
            runMi.Invoke(obj, null);
        }

        public static void Test1() {
            var driver = new Driver(new Car());
            driver.Drive();
            driver = new Driver(new HeavyTank());
            driver.Drive();
        }
    }

    class Driver {
        private IVehicle _vehicle;
        public Driver(IVehicle vehicle) {
            _vehicle = vehicle;
        }

        public void Drive() {
            _vehicle.Run();
        }
    }


    interface IVehicle {
        void Run();
    }

    class Car : IVehicle {
        public void Run() {
            Console.WriteLine("Car is running...");
        }
    }

    class Truck : IVehicle {
        public void Run() {
            Console.WriteLine("Truck is running...");
        }
    }

    interface IWeapon {
        void Fire();
    }

    interface ITank : IWeapon, IVehicle {
    }

    class LightTank : ITank {
        public void Fire() {
            Console.WriteLine("Boom!");
        }

        public void Run() {
            Console.WriteLine("Ka ka ka ...");
        }
    }

    class MediumTank : ITank {
        public void Fire() {
            Console.WriteLine("Boom!");
        }

        public void Run() {
            Console.WriteLine("Ka! ka! ka! ...");
        }
    }

    class HeavyTank : ITank {
        public void Fire() {
            Console.WriteLine("Boom!!!!");
        }

        public void Run() {
            Console.WriteLine("Ka!!! ka!!! ka!!! ...");
        }
    }
}
